﻿using System;
using System.Windows;
using FastColoredTextBoxNS;
using System.Collections.Generic;
using System.Text.RegularExpressions;


namespace MPE
{
    public partial class replaceWindow : Window
    {
        public replaceWindow() { InitializeComponent(); tbFind.Focus(); }
        Place startPlace;
        FastColoredTextBox tb { get => DataHelper.field; }
        bool firstSearch = true;
        public void setTextInFindTB(string text) { tbFind.Text = text; }
        void BtFindNext_Click(object sender, RoutedEventArgs e)
        {
            try { if (!Find(tbFind.Text)) { firstSearch = true; } }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }
        List<Range> FindAll(string pattern)
        {
            var opt = cbMatchCase.IsChecked == true ? RegexOptions.None : RegexOptions.IgnoreCase;
            if (!cbRegex.IsChecked == true)
                pattern = Regex.Escape(pattern);
            if (cbWholeWord.IsChecked == true)
                pattern = "\\b" + pattern + "\\b";

            var range = tb.Selection.IsEmpty ? tb.Range.Clone() : tb.Selection.Clone();

            var list = new List<Range>();
            foreach (var r in range.GetRangesByLines(pattern, opt))
                list.Add(r);

            return list;
        }
        bool Find(string pattern)
        {
            RegexOptions opt = cbMatchCase.IsChecked == true ? RegexOptions.None : RegexOptions.IgnoreCase;
            if (!cbRegex.IsChecked == true)
                pattern = Regex.Escape(pattern);
            if (cbWholeWord.IsChecked == true)
                pattern = "\\b" + pattern + "\\b";

            Range range = tb.Selection.Clone();
            range.Normalize();

            if (firstSearch)
            {
                startPlace = range.Start;
                firstSearch = false;
            }

            range.Start = range.End;
            if (range.Start >= startPlace)
                range.End = new Place(tb.GetLineLength(tb.LinesCount - 1), tb.LinesCount - 1);
            else
            {
                range.End = startPlace;
                //firstSearch = true;
            }

            foreach (var r in range.GetRangesByLines(pattern, opt))
            {
                tb.Selection.Start = r.Start;
                tb.Selection.End = r.End;
                tb.DoSelectionVisible();
                tb.Invalidate();
                return true;
            }
            if (range.Start >= startPlace && startPlace > Place.Empty)
            {
                tb.Selection.Start = new Place(0, 0);
                return Find(pattern);
            }
            firstSearch = true;
            tb.Selection.Start = new Place(0, 0);
            tb.Selection.End = new Place(0, 0);
            return false;
        }
        void BtReplace_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                if (tb.SelectionLength != 0) tb.InsertText(tbReplace.Text);
                BtFindNext_Click(sender, null);
            }
            catch (Exception ex)
            { MessageBox.Show(ex.Message); }
        }
        void BtReplaceAll_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                tb.Selection.BeginUpdate();

                var ranges = FindAll(tbFind.Text);

                if (ranges.Count > 0)
                {
                    tb.TextSource.Manager.ExecuteCommand(new ReplaceTextCommand(tb.TextSource, ranges, tbReplace.Text));
                    tb.Selection.Start = new Place(0, 0);
                    tb.Invalidate();
                    MessageBox.Show(ranges.Count + " вхождений заменено");
                }
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
            tb.Selection.EndUpdate();
        }
        void Window_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e) => DragMove();
        void TbFind_KeyUp(object sender, System.Windows.Input.KeyEventArgs e) { if (e.Key == System.Windows.Input.Key.Enter) { Find(tbFind.Text); e.Handled = true; return; } }
    }
}